﻿@namespace AntDesign
@inherits AntDomComponentBase
@using AntDesign.TableModels
@typeparam TItem

<div class="@_wrapperClassMapper.Class" @ref="Ref">
    <Spin Spinning="Loading">
        @if (!HidePagination && PaginationPosition.Contains("top"))
        {
            if (PaginationTemplate == null)
            {
                <Pagination Class="@_paginationClass"
                            Total="_total"
                            PageSize="PageSize"
                            Current="PageIndex"
                            OnChange="HandlePageChange" />
            }
            else
            {
                @PaginationTemplate
            }
        }

        <CascadingValue Value="@this" TValue="ITable" IsFixed>
            <CascadingValue Value=@typeof(TItem) Name="ItemType" IsFixed>
                <CascadingValue Value="@ColumnContext" IsFixed>
                    <CascadingValue Name="IsInitialize" Value="true" IsFixed>
                        @ChildContent(_fieldModel)
                    </CascadingValue>
                    <div class="@ClassMapper.Class" @ref="_tableRef">
                        @if (TitleTemplate != null || Title != null)
                        {
                            <div class="ant-table-title">
                                @if (TitleTemplate != null)@TitleTemplate else @Title
                            </div>
                        }
                        <div class="ant-table-container">
                            @if (ScrollY != null)
                            {
                                <div class="ant-table-header" style="overflow: hidden;" @ref="_tableHeaderRef">
                                    <table style="@TableLayoutStyle">
                                        @colGroup((this, true))
                                        @header(this)
                                    </table>
                                </div>
                                <div class="ant-table-body" @ref="_tableBodyRef" style="@(ScrollX!=null?" overflow: auto scroll;":"overflow-y: scroll;") max-height: @((CssSizeLength)ScrollY)">
                                    <table style="@(ScrollX!=null?$" width: {(CssSizeLength)ScrollX}; min-width: 100%;":"") @TableLayoutStyle">
                                        @colGroup((this, false))
                                        <tbody class="ant-table-tbody">
                                            <tr aria-hidden="true" class="ant-table-measure-row" style="height: 0px; font-size: 0px;">
                                                <CascadingValue Name="IsMeasure" Value="true" IsFixed>
                                                    @ChildContent(_fieldModel)
                                                </CascadingValue>
                                            </tr>
                                            @body((this, _showItems, 0))
                                        </tbody>
                                        @tfoot(this)
                                    </table>
                                </div>
                            }
                            else if (ScrollX != null)
                            {
                                <div class="ant-table-content" @ref="_tableBodyRef" style="overflow: auto hidden;">
                                    <table style="width: @((CssSizeLength)ScrollX); min-width: 100%; @TableLayoutStyle">
                                        @colGroup((this, true))
                                        @header(this)
                                        <tbody class="ant-table-tbody">
                                            <tr aria-hidden="true" class="ant-table-measure-row" style="height: 0px; font-size: 0px;">
                                                <CascadingValue Name="IsMeasure" Value="true" IsFixed>
                                                    @ChildContent(_fieldModel)
                                                </CascadingValue>
                                            </tr>
                                            @body((this, _showItems, 0))
                                        </tbody>
                                        @tfoot(this)
                                    </table>
                                </div>
                            }
                            else
                            {
                                <div class="ant-table-content">
                                    <table style="@TableLayoutStyle">
                                        @colGroup((this, true))
                                        @header(this)
                                        <tbody class="ant-table-tbody">
                                            @body((this, _showItems, 0))
                                        </tbody>
                                        @tfoot(this)
                                    </table>
                                </div>
                            }
                        </div>
                        @if (FooterTemplate != null || Footer != null)
                        {
                            <div class="ant-table-footer">
                                @if (FooterTemplate != null)@FooterTemplate else @Footer
                            </div>
                        }
                    </div>
                </CascadingValue>
            </CascadingValue>
        </CascadingValue>
        @if (!HidePagination && PaginationPosition.Contains("bottom"))
        {
            if (PaginationTemplate == null)
            {
                <Pagination Class="@_paginationClass"
                            Total="_total"
                            PageSize="PageSize"
                            Current="PageIndex"
                            OnChange="HandlePageChange" />
            }
            else
            {
                @PaginationTemplate
            }
        }
    </Spin>
</div>

@code
{
    RenderFragment<Table<TItem>> header = table =>
    @<Template>
        @{
            var headerRowAttributes = table.OnHeaderRow?.Invoke();
        }
         <thead class="ant-table-thead">
             <CascadingValue Name="IsHeader" Value="true" IsFixed>
                 <CascadingValue Value="table" Name="AntDesign.TableRow.Table">
                     <AntDesign.Internal.TableRow TItem="TItem">
                         @table.ChildContent(_fieldModel)
                         @if (table.ScrollY != null)
                         {
                             <th class="ant-table-cell @(table._hasFixRight?"ant-table-cell-fix-right":"") ant-table-cell-scrollbar" style="@(table._hasFixRight?"position: sticky; right: 0px;":"")"></th>
                         }
                     </AntDesign.Internal.TableRow>
                 </CascadingValue>
             </CascadingValue>
         </thead>
    </Template>;

RenderFragment<(Table<TItem> table, bool header)> colGroup = ctx =>
@<Template>
    @{
        var table = ctx.table;
        var header = ctx.header;
    }
    <colgroup>
        <CascadingValue Name="IsColGroup" Value="true" IsFixed>
            @table.ChildContent(_fieldModel)
        </CascadingValue>
        @if (table.ScrollY != null && header)
        {
            <col style="width: @((CssSizeLength)table.ScrollBarWidth); min-width: @((CssSizeLength)table.ScrollBarWidth);" />
        }
    </colgroup>
</Template>;

RenderFragment<(Table<TItem> table, IEnumerable<TItem> showItems, int level)> body = context =>
@<Template>
    @{
        var table = context.table;
        var showItems = context.showItems;
        var level = context.level;
    }

    @if (table._total <= 0)
    {
        <tr class="ant-table-placeholder">
            <td colspan="@(table.ColumnContext.Columns.Count + (table.ExpandTemplate != null? 1 : 0))" class="ant-table-cell">
                <Empty Simple />
            </td>
        </tr>
    }
    else if (showItems != null && table.ColumnContext.Columns.Count > 0)
    {
        for (int i = 0; i < showItems.Count(); i++)
        {
            var rowIndex = table.PageSize * (table.PageIndex - 1) + i + 1;
            var data = showItems.ElementAt(i);
            var cacheKey = data.GetHashCode();
            if (!table._dataSourceCache.ContainsKey(cacheKey) || table._dataSourceCache[cacheKey] == null)
            {
                var rowData = new RowData<TItem>(rowIndex, table.PageIndex, data)
                {
                    Expanded = table.DefaultExpandAllRows
                };
                rowData.SelectedChanged += table.RowDataSelectedChanged;
                table._dataSourceCache[cacheKey] = rowData;
            }
            var currentRowData = table._dataSourceCache[cacheKey];
            var childrenData = table.TreeChildren(data);
            var hasChildren = childrenData?.Any() == true;
            currentRowData.CacheKey = cacheKey;
            currentRowData.Level = level;
            currentRowData.HasChildren = hasChildren;
            currentRowData.RowIndex = rowIndex;
            currentRowData.PageIndex = table.PageIndex;

            <CascadingValue Value="currentRowData" Name="RowData" IsFixed="false">
                <CascadingValue Value="true" Name="IsBody" IsFixed>
                    <CascadingValue Value="table" Name="AntDesign.TableRow.Table">
                        <AntDesign.Internal.TableRow @key="currentRowData" TItem="TItem">
                            @table.ChildContent(data)
                        </AntDesign.Internal.TableRow>
                    </CascadingValue>                        
                </CascadingValue>
            </CascadingValue>

            @if (hasChildren && currentRowData.Expanded)
            {
                @table.body((table, table.SortFilterChildren(childrenData), level + 1));
            }
            @if (!hasChildren && table.ExpandTemplate != null && table.RowExpandable(currentRowData) && currentRowData.Expanded)
            {
                <tr class="ant-table-expanded-row ant-table-expanded-row-level-1 @table.ExpandedRowClassName(currentRowData)"
                    style="@(currentRowData.Expanded?"":"display: none;")">
                    <td colspan="@(table.ColumnContext.Columns.Count+1)" class="ant-table-cell">
                        @table.ExpandTemplate(currentRowData)
                    </td>
                </tr>
            }
        }
    }
</Template>;

RenderFragment<Table<TItem>> tfoot = table =>@<Template>
    @if (table._summaryRows?.Any() == true)
    {
        <CascadingValue Value="true" Name="IsSummary" IsFixed>
            <tfoot class="ant-table-summary">
                @foreach (var row in table._summaryRows)
                {
                    <tr>
                        @row.ChildContent
                    </tr>
                }
            </tfoot>
        </CascadingValue>
    }
</Template>;
}
